package com.fenfen.novel.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.fenfen.novel.ChapterActivity;
import com.fenfen.novel.MainActivity;
import com.fenfen.novel.R;
import com.fenfen.novel.adapter.NovelReadRecordAdapter;
import com.fenfen.novel.db.NovelDBProvider;
import com.fenfen.novel.db.NovelReadRecord;
import com.fenfen.novel.model.Chapter;
import com.fenfen.novel.service.NovelDownService;
import com.fenfen.novel.utils.CommonUtil;
import com.fenfen.novel.utils.NovelRecordHandlerThread;

import org.parceler.Parcels;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NovelReadLogFragment extends Fragment implements NovelReadRecordAdapter.NovelRecordItemClickListener, ActionMode.Callback {
  private static String Tag = NovelReadLogFragment.class.getSimpleName();

  private RecyclerView recyclerView;
  private NovelReadRecordAdapter adapter;
  private int page;
  private boolean isLoading;

  private TextView noDataTv;

  private NovelRecordHandlerThread dbThread;

  public static byte dataStatus = CommonUtil.DB_DATA_STATUS.NEWEST; //默认最新

  private ActionMode mActionMode;
  private Map<Integer, NovelReadRecord> selectedData = new HashMap<>(); //长按选择后的数据

  public static Fragment newInstance(Bundle bundle) {
    NovelReadLogFragment fragment = new NovelReadLogFragment();
    fragment.setArguments(bundle);
    return fragment;
  }

  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_read_log, container, false);
    recyclerView = (RecyclerView) view.findViewById(R.id.novel_recyclerview);

    noDataTv = (TextView) view.findViewById(R.id.no_novel_data);
    GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.addOnScrollListener(new MyOnScrollListener());
    adapter = new NovelReadRecordAdapter(getActivity());
    adapter.setHasLoadingMore(true);
    adapter.setNovalItemClickListener(this);
    recyclerView.setAdapter(adapter);
    page = CommonUtil.FIRST_PAGE;

    dbThread = new NovelRecordHandlerThread(getActivity(), new Handler(getActivity().getMainLooper()));
    dbThread.start();
    dbThread.setHandlerListener(new MyDbListener());
    dbThread.getLooper();

    loadData();

    mActionMode = ((MainActivity) getActivity()).getActionMode();
    return view;
  }

  @Override
  public void onResume() {
    super.onResume();
    if (!isLoading() && dataStatus == CommonUtil.DB_DATA_STATUS.UPDATE) {
      mActionMode = null;
      selectedData.clear();
      ((MainActivity) getActivity()).setActionMode(null);
      page = CommonUtil.FIRST_PAGE;
      loadData();
    }
  }

  public static void setDataStatus(byte status) {
    dataStatus = status;
  }

  public static byte getDataStatus() {
    return dataStatus;
  }

  public boolean isLoading() {
    return isLoading;
  }

  private void loadData() {
    isLoading = true;
    if (dbThread != null) {
      dbThread.queryByPage(page);
    }
  }

  @Override
  public void onItemClick(View v, int position, NovelReadRecord record) {
    if (mActionMode != null) {
      boolean isActivated = v.isActivated();
      Log.d(Tag, "item click isactivated=" + isActivated);
      v.setActivated(!isActivated);
      if (selectedData.get(position) != null) {
        selectedData.remove(position);
      } else {
        selectedData.put(position, record);
      }
      updateActionModeTitle();
      if (selectedData.size() == 0) {
        mActionMode.finish();
      }
      return;
    }
    //just jump to read page
    Intent intent = new Intent(getActivity(), ChapterActivity.class);
    Chapter chapter = new Chapter();
    chapter.setNovelId(record.getNovelId());
    chapter.setChapterOrder(record.getChapterOrder());
    intent.putExtra(ChapterActivity.EXTRA_CHAPTER, Parcels.wrap(chapter));
    intent.putExtra(ChapterActivity.EXTRA_CHAPTER_COUNT, record.getChapterCount());
    startActivity(intent);
  }

  @Override
  public boolean onItemLongClick(View v, int position, NovelReadRecord record) {
    if (mActionMode != null) {
      return false;
    }
    mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(this);
    ((MainActivity) getActivity()).setActionMode(mActionMode);
    selectedData.clear();
    selectedData.put(position, record);
    updateActionModeTitle();
    recyclerView.getChildAt(position).setActivated(true);
    return true;
  }

  private void updateActionModeTitle() {
    if (mActionMode == null) {
      return;
    }
    mActionMode.setTitle(String.format(getString(R.string.already_select_num), selectedData.size()));
  }

  @Override
  public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    getActivity().getMenuInflater().inflate(R.menu.menu_read_log, menu);
    return true;
  }

  @Override
  public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    return false;
  }

  @Override
  public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
    switch (item.getItemId()) {
      case R.id.delete_read_log:
        StringBuilder titles = new StringBuilder();
        int index = 0;
        boolean containDownload = false;
        for (Map.Entry<Integer, NovelReadRecord> entry : selectedData.entrySet()) {
//          int position = entry.getKey();
          index++;
          NovelReadRecord record = entry.getValue();
          if (record.getDownStatus().equals(CommonUtil.DOWN_STATUS.SUCCESS)) {
            containDownload = true;
          }
          titles.append(index + ".").append(record.getNovelName()).append("\n");
        }
        MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
            .title(String.format(getString(R.string.confirm_delete), index))
            .customView(R.layout.dialog_delete_record, true)
            .positiveText(getString(R.string.action_sure))
            .negativeText(getString(R.string.action_cancel))
            .onPositive(new MaterialDialog.SingleButtonCallback() {
              @Override
              public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                CheckBox cb = (CheckBox) dialog.getCustomView().findViewById(R.id.delete_text);
                boolean isDeleteText = cb.isChecked();
                ArrayList<Integer> positions = new ArrayList<>();
                for (Map.Entry<Integer, NovelReadRecord> entry : selectedData.entrySet()) {
                  int position = entry.getKey();
                  NovelReadRecord record = entry.getValue();
                  boolean isSuccess = NovelDBProvider.getInstance(getActivity()).deleteReadRecord(record.getNovelId());
                  Log.d(Tag, "delete name=" + record.getNovelName() + ",position=" + position +", result:" + isSuccess);
                  if (isSuccess) {
                    positions.add(position);
                    NovelDBProvider.getInstance(getActivity()).removeDownRecord(record.getNovelId());
                    if (isDeleteText) {
                      String filePath = CommonUtil.getNovelFilePath(getActivity(), record.getNovelId());
                      File novelTxt = new File(filePath);
                      if (novelTxt.exists()) {
                        novelTxt.delete();
                      }
                    }
                  } else {
                    CommonUtil.showSnack(recyclerView, String.format(getString(R.string.delete_novel_error), record.getNovelName()));
                    break;
                  }
                }
                adapter.removeItems(positions);
                if(0 == adapter.getItemCount()) {
                  noDataTv.setVisibility(View.VISIBLE);
                }
                mode.finish();
              }
            })
            .build();
        TextView tv = (TextView) dialog.getCustomView().findViewById(R.id.titles);
        tv.setText(titles);
        CheckBox cb = (CheckBox) dialog.getCustomView().findViewById(R.id.delete_text);
        if (!containDownload) {
          cb.setVisibility(View.GONE);
          cb.setChecked(false);
        }
        dialog.show();
        break;
      case R.id.download_novel:
        for (Map.Entry<Integer, NovelReadRecord> entry : selectedData.entrySet()) {
          NovelReadRecord record = entry.getValue();
          dbThread.saveDownStatus(record);
          Intent novelDownService = new Intent(getActivity(), NovelDownService.class);
          getActivity().startService(novelDownService);
        }
        if (selectedData.size() > 0) {
          CommonUtil.showSnack(recyclerView, getString(R.string.start_down));
        }
        mode.finish();
        break;
      default:
        mode.finish();
        break;
    }
    return true;
  }

  @Override
  public void onDestroyActionMode(ActionMode mode) {
    mActionMode = null;
    ((MainActivity) getActivity()).setActionMode(null);
    for (Map.Entry<Integer, NovelReadRecord> entry : selectedData.entrySet()) {
      int pos = entry.getKey();
      recyclerView.getChildAt(pos).setActivated(false);
    }
    selectedData.clear();
  }

  private class MyOnScrollListener extends RecyclerView.OnScrollListener {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
      super.onScrolled(recyclerView, dx, dy);
      boolean hasLoadingMore = adapter.isHasLoadingMore();
      if (hasLoadingMore) {
        if (isLoading()) {
          return;
        }
        int lastVisiblePosition = ((GridLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition();
        if (adapter.getItemCount() > 0 && lastVisiblePosition + CommonUtil.LOAD_MORE_ITEM > adapter.getItemCount()) {
          Log.d(Tag, "lastVisiblePosition=" + lastVisiblePosition + ",current itemCount=" + adapter.getItemCount());
          isLoading = true;
          loadData();
        }
      }
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
      super.onScrollStateChanged(recyclerView, newState);
    }
  }

  private class MyDbListener extends NovelRecordHandlerThread.HandlerListener {
    @Override
    public void onQueryList(List<NovelReadRecord> list) {
      isLoading = false;
      setDataStatus(CommonUtil.DB_DATA_STATUS.NEWEST);
      if (list == null || list.size() <= 0) {
        adapter.setHasLoadingMore(false);
        if (adapter.getItemCount() == 0) {
          noDataTv.setVisibility(View.VISIBLE);
        }
        return;
      }
      if (page == CommonUtil.FIRST_PAGE) {
        adapter.setData(list);
      } else {
        adapter.addData(list);
      }
      noDataTv.setVisibility(View.GONE);
      page++;
    }
  }
}
